﻿using System;
using System.Runtime.InteropServices;

namespace Microsoft.Xna.Framework
{
    /// <summary>
    /// Defines a point in 2D space.
    /// </summary>
    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct Point : IEquatable<Point>
    {
        #region Public Fields
        /// <summary>
        /// Specifies the x-coordinate of the Point.
        /// </summary>
        public int X;
        /// <summary>
        /// Specifies the y-coordinate of the Point.
        /// </summary>
        public int Y;
        #endregion

        #region Properties
        /// <summary>
        /// Returns the point (0,0).
        /// </summary>
        public static Point Zero
        {
            get { return new Point(); }
        }
        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of Point.
        /// </summary>
        /// <param name="x">The x-coordinate of the Point.</param>
        /// <param name="y">The y-coordinate of the Point.</param>
        public Point(int x, int y)
        {
            X = x;
            Y = y;
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Determines whether two Point instances are equal.
        /// </summary>
        /// <param name="obj">The object to compare this instance to.</param>
        public override bool Equals(object obj)
        {
            return (obj is Point) ? Equals((Point)obj) : false;
        }
        /// <summary>
        /// Determines whether two Point instances are equal.
        /// </summary>
        /// <param name="other">The object to compare this instance to.</param>
        public bool Equals(Point other)
        {
            return ((X == other.X) && (Y == other.Y));
        }
        /// <summary>
        /// Gets the hash code for this object.
        /// </summary>
        public override int GetHashCode()
        {
            return X ^ Y;
        }
        /// <summary>
        /// Returns a String that represents the current Point.
        /// </summary>
        public override string ToString()
        {
            return string.Format("{{X:{0} Y:{1}}}", X, Y);
        }
        #endregion

        #region Operators
        /// <summary>
        /// Determines whether two Point instances are equal.
        /// </summary>
        /// <param name="a">The Point on the left side of the equal sign.</param>
        /// <param name="b">The Point on the right side of the equal sign.</param>
        public static bool operator ==(Point a, Point b)
        {
            return ((a.X == b.X) && (a.Y == b.Y));
        }
        /// <summary>
        /// Determines whether two Point instances are not equal.
        /// </summary>
        /// <param name="a">The Point on the left side of the equal sign.</param>
        /// <param name="b">The Point on the right side of the equal sign.</param>
        public static bool operator !=(Point a, Point b)
        {
            return !(a == b);
        }
        #endregion
    }
}
